// 1.实例化
/*
    使用new操作符实例化Person == 使用new调用其构造函数
        1). 在内存中创建一个新对象
        2). 将新对象内部的__proto__指向构造函数的prototype属性
        3). 构造函数内部的this被赋值给这个新的对象（this指向新对象）
        4). 执行构造函数内部的代码（给新对象添加属性）
        5). 如果构造函数返回非空对象，就返回这个对象；否则，返回刚创建的新对象
*/

class Person {
    constructor(name) {
        this.name = name;
        console.log(this.name);
    };
};


let p = new Person('Katrina');
console.log(p.name);  // Katrina

// new 的过程如下：
function myNew() {
    let myClass = Array.prototype.shift.call(arguments);   // 获取到构造函数
    let Constructor = myClass.constructor;  // 获取到构造函数的prototype属性

    // let newObj = {};   // Step1. 新建对象
    let newObj = Object.create(Constructor.prototype);   // Step2. 新对象的__proto__指向prototype
    Constructor.call(newObj, ...arguments);    // Step3 4. 修改this指向，把this指向newObj，并且执行
    return newObj;
};

let p1 = myNew(Person, 'Katrina');   // Katrina


// 2. 返回不是this对象的情况： instanceof 检测不到，因为原型指针没有被修改
class Persion {
    constructor(override) {
        this.foo = 'foo';

        if (override) {
            // @ts-ignore
            return {
                // @ts-ignore
                bar: 'bar'
            };
        };
    };
};


let p3 = new Persion();
let p4 = new Persion(true);

console.log(p3, p4);
console.log(p4 instanceof Persion) // false


// 3. 类构造函数必须使用new操作符
// 4. 类构造函数实例化后会变成普通的实例方法，实例化之后可以通过new 在实例上继续调用


// 5. typeof class = function  instanceof检测实例原型链中是否有类构造函数的原型

// 6. 类标识符有prototype属性
class Fn{
    constructor() {};
};
console.log(Fn.prototype);  // {}
console.log(Fn.prototype.constructor === Fn) // true

// 7. 类中定义的constructor方法不会被当成构造函数，使用instaceof会返回false


// 8. 类可以作为参数进行传递

// 9. 类可以立即实例化
let ppp = new class Poo{
    constructor(x) {
        console.log(x);
    }
}('bar');   // bar
console.log(ppp);  // Poo{}



